import React, { useRef, useState, useEffect, useCallback } from "react";
import SparkMD5 from "spark-md5";
import axios from "axios";
import { Button, Progress, Upload, Typography, message } from "antd";
import { UploadOutlined, PauseOutlined, PlayCircleOutlined } from "@ant-design/icons";

const CHUNK_SIZE = 2 * 1024 * 1024; // 2MB
const MAX_CONCURRENT = 3; // 最大并发数

type Chunk = {
  file: Blob;
  index: number;
  start: number;
  end: number;
  progress: number;
};

type CancelToken = ReturnType<typeof axios.CancelToken.source>;

type UploadInfo = {
  target?: { files?: FileList };
  file?: File;
};

const Order: React.FC = () => {
  const [file, setFile] = useState<File | null>(null);
  const [hash, setHash] = useState<string>("");
  const [chunks, setChunks] = useState<Chunk[]>([]);
  const [progress, setProgress] = useState<number>(0);
  const [uploading, setUploading] = useState(false);
  const [paused, setPaused] = useState(false);
  const [isDarkTheme, setIsDarkTheme] = useState(false);
  const [uploadSpeed, setUploadSpeed] = useState<string>("");
  const [remainingTime, setRemainingTime] = useState<string>("");
  const [startTime, setStartTime] = useState<number>(0);
  const cancelTokens = useRef<CancelToken[]>([]);

  // 优化的主题检测和监听
  const checkTheme = useCallback(() => {
    const localThemeMode = localStorage.getItem('themeMode') || 'system';
    let currentTheme = localThemeMode;
    
    // 如果设置为跟随系统，则检测系统主题
    if (localThemeMode === 'system') {
      currentTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
    }
    
    const bodyTheme = document.body.dataset.theme || 
                     (document.body.classList.contains('dark') ? 'dark' : 'light');
    const finalTheme = currentTheme || bodyTheme;
    setIsDarkTheme(finalTheme === 'dark');
  }, []);

  useEffect(() => {
    checkTheme();

    const observer = new MutationObserver(checkTheme);
    observer.observe(document.body, { 
      attributes: true, 
      attributeFilter: ['data-theme', 'class'] 
    });

    const handleStorageChange = () => {
      checkTheme();
    };
    window.addEventListener('storage', handleStorageChange);
    
    // 监听系统主题变化
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleSystemThemeChange = () => {
      const localThemeMode = localStorage.getItem('themeMode') || 'system';
      if (localThemeMode === 'system') {
        checkTheme();
      }
    };
    mediaQuery.addEventListener('change', handleSystemThemeChange);

    return () => {
      observer.disconnect();
      window.removeEventListener('storage', handleStorageChange);
      mediaQuery.removeEventListener('change', handleSystemThemeChange);
    };
  }, [checkTheme]);

  // 计算上传速度和剩余时间
  const calculateUploadStats = useCallback((loaded: number, total: number) => {
    if (startTime === 0) return;
    
    const elapsed = (Date.now() - startTime) / 1000; // 秒
    const speed = loaded / elapsed; // 字节/秒
    const remaining = (total - loaded) / speed; // 秒
    
    setUploadSpeed(formatBytes(speed));
    setRemainingTime(formatTime(remaining));
  }, [startTime]);

  const formatBytes = (bytes: number): string => {
    if (bytes === 0) return '0 B/s';
    const k = 1024;
    const sizes = ['B/s', 'KB/s', 'MB/s', 'GB/s'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  };

  const formatTime = (seconds: number): string => {
    if (seconds < 0 || !isFinite(seconds)) return '计算中...';
    const hours = Math.floor(seconds / 3600);
    const minutes = Math.floor((seconds % 3600) / 60);
    const secs = Math.floor(seconds % 60);
    
    if (hours > 0) return `${hours}小时${minutes}分钟`;
    if (minutes > 0) return `${minutes}分钟${secs}秒`;
    return `${secs}秒`;
  };

  // 选择文件
  const handleFileChange = async (info: UploadInfo) => {
    const f = info?.target?.files?.[0] || info?.file;
    if (!f) return;
    
    // 文件大小检查
    const maxSize = 1024 * 1024 * 1024; // 1GB
    if (f.size > maxSize) {
      message.error('文件大小不能超过1GB');
      return;
    }
    
    setFile(f);
    setProgress(0);
    setPaused(false);
    setUploading(false);
    setUploadSpeed("");
    setRemainingTime("");

    // 1. 计算hash
    message.loading({ content: "正在计算文件Hash...", key: "hash" });
    try {
    const hash = await calculateHash(f);
    setHash(hash);
    message.success({ content: "Hash计算完成", key: "hash", duration: 1 });
    } catch {
      message.error({ content: "Hash计算失败", key: "hash", duration: 2 });
      return;
    }

    // 2. 切片
    const chunks = createChunks(f);
    setChunks(chunks);

    // 3. 检查已上传（断点/秒传）
    try {
      const checkRes = await checkFile(hash, f.name);
      if (checkRes.uploaded) {
        setProgress(100);
        message.success("文件已秒传！");
        return;
      }
    } catch {
      message.error("检查文件状态失败");
    }
  };

  // 计算文件hash
  const calculateHash = (file: File) => {
    return new Promise<string>((resolve, reject) => {
      const spark = new SparkMD5.ArrayBuffer();
      const reader = new FileReader();
      const chunkSize = CHUNK_SIZE;
      const chunks = Math.ceil(file.size / chunkSize);
      let currentChunk = 0;

      function loadNext() {
        const start = currentChunk * chunkSize;
        const end = Math.min(file.size, start + chunkSize);
        reader.readAsArrayBuffer(file.slice(start, end));
      }

      reader.onload = (e) => {
        spark.append(e.target?.result as ArrayBuffer);
        currentChunk++;
        if (currentChunk < chunks) {
          loadNext();
        } else {
          resolve(spark.end());
        }
      };
      reader.onerror = reject;
      loadNext();
    });
  };

  // 切片
  const createChunks = (file: File): Chunk[] => {
    const chunks: Chunk[] = [];
    let cur = 0, idx = 0;
    while (cur < file.size) {
      chunks.push({
        file: file.slice(cur, cur + CHUNK_SIZE),
        index: idx++,
        start: cur,
        end: Math.min(cur + CHUNK_SIZE, file.size),
        progress: 0,
      });
      cur += CHUNK_SIZE;
    }
    return chunks;
  };

  // 检查文件/断点/秒传
  const checkFile = async (hash: string, filename: string) => {
    const res = await axios.post("/upload/check", { fileHash: hash, filename });
    // 返回 { uploaded: boolean, uploadedChunks: string[] }
    return res.data;
  };

  // 上传切片
  const uploadChunk = (chunk: Chunk, hash: string) => {
    const formData = new FormData();
    formData.append("chunk", chunk.file);
    formData.append("fileHash", hash);
    formData.append("chunkIndex", chunk.index.toString());

    const source = axios.CancelToken.source();
    cancelTokens.current[chunk.index] = source;

    return axios.post("/upload/chunk", formData, {
      onUploadProgress: (e) => {
        chunk.progress = e.total ? (e.loaded / e.total) * 100 : 0;
        setChunks((prev) => [...prev]);
        calculateUploadStats(e.loaded, e.total || 0);
      },
      cancelToken: source.token,
      timeout: 30000, // 30秒超时
    });
  };

  // 并发上传
  const startUpload = async () => {
    if (!file || !hash || chunks.length === 0) return;
    setUploading(true);
    setPaused(false);
    setStartTime(Date.now());

    try {
    // 检查已上传切片
    const checkRes = await checkFile(hash, file.name);
    if (checkRes.uploaded) {
      setProgress(100);
      message.success("文件已秒传！");
      setUploading(false);
      return;
    }
    const uploadedChunks = (checkRes.uploadedChunks || []).map(Number);

    // 过滤已上传
    const needUpload = chunks.filter((c) => !uploadedChunks.includes(c.index));
    let finished = uploadedChunks.length;
    const total = chunks.length;

    let pool: Promise<unknown>[] = [];
    let i = 0;
    let hasError = false;
      let retryCount = 0;
      const maxRetries = 3;

    const run = async () => {
      while (i < needUpload.length && pool.length < MAX_CONCURRENT && !paused && !hasError) {
        const chunk = needUpload[i++];
        const p = uploadChunk(chunk, hash)
          .then(() => {
            finished++;
            setProgress(Math.round((finished / total) * 100));
              retryCount = 0; // 重置重试计数
          })
          .catch((err) => {
            if (!axios.isCancel(err)) {
                retryCount++;
                if (retryCount <= maxRetries) {
                  message.warning(`切片${chunk.index}上传失败，正在重试... (${retryCount}/${maxRetries})`);
                  i--; // 重新尝试这个切片
                  setTimeout(() => run(), 1000); // 1秒后重试
                } else {
              hasError = true;
                  message.error(`切片${chunk.index}上传失败，已达到最大重试次数`);
              setUploading(false);
                }
            }
          })
          .finally(() => {
            pool = pool.filter((item) => item !== p);
            if (!paused && !hasError) run();
          });
        pool.push(p);
      }
      if (finished === total && !paused && !hasError) {
        // 合并切片
          try {
        await axios.post("/upload/merge", {
          fileHash: hash,
          filename: file.name,
          chunkSize: CHUNK_SIZE
        });
        setUploading(false);
        setProgress(100);
        message.success("上传完成！");
          } catch {
            message.error("文件合并失败，请重试");
            setUploading(false);
          }
      }
    };

    run();
    } catch {
      message.error("开始上传失败，请重试");
      setUploading(false);
    }
  };

  // 暂停
  const handlePause = () => {
    setPaused(true);
    cancelTokens.current.forEach((token) => token && token.cancel && token.cancel());
    setUploading(false);
  };

  // 恢复
  const handleResume = () => {
    setPaused(false);
    startUpload();
  };

  // 优化UI
  return (
    <div style={{ 
      minHeight: 'calc(100vh - 120px)', 
      display: 'flex', 
      alignItems: 'center', 
      justifyContent: 'center', 
      background: isDarkTheme 
        ? 'linear-gradient(135deg, #001529 0%, #003a70 50%, #001529 100%)' 
        : 'linear-gradient(135deg, #f5f6fa 0%, #e6f7ff 50%, #f5f6fa 100%)',
      transition: 'background 0.3s ease',
      padding: '20px',
      position: 'relative',
      overflow: 'hidden'
    }}>
      {/* 背景装饰 */}
      <div style={{
        position: 'absolute',
        top: '10%',
        left: '10%',
        width: '200px',
        height: '200px',
        borderRadius: '50%',
        background: isDarkTheme 
          ? 'radial-gradient(circle, rgba(23, 125, 220, 0.1) 0%, transparent 70%)' 
          : 'radial-gradient(circle, rgba(22, 119, 255, 0.1) 0%, transparent 70%)',
        animation: 'float 6s ease-in-out infinite'
      }} />
      <div style={{
        position: 'absolute',
        bottom: '10%',
        right: '10%',
        width: '150px',
        height: '150px',
        borderRadius: '50%',
        background: isDarkTheme 
          ? 'radial-gradient(circle, rgba(73, 170, 25, 0.1) 0%, transparent 70%)' 
          : 'radial-gradient(circle, rgba(82, 196, 26, 0.1) 0%, transparent 70%)',
        animation: 'float 8s ease-in-out infinite reverse'
      }} />
      
      <div style={{ 
        width: '100%',
        maxWidth: 520,
        background: isDarkTheme 
          ? 'linear-gradient(145deg, #1f1f1f 0%, #2a2a2a 100%)' 
          : 'linear-gradient(145deg, #ffffff 0%, #fafafa 100%)', 
        borderRadius: 24, 
        boxShadow: isDarkTheme 
          ? '0 20px 60px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.05)' 
          : '0 20px 60px rgba(0,0,0,0.1), 0 0 0 1px rgba(255,255,255,0.8)', 
        padding: 48, 
        margin: '20px 0',
        border: isDarkTheme ? '1px solid #404040' : '1px solid #f0f0f0',
        transition: 'all 0.3s ease',
        position: 'relative',
        overflow: 'hidden',
        backdropFilter: 'blur(10px)'
      }}>
        {/* 装饰性顶部条 */}
        <div style={{
          position: 'absolute',
          top: 0,
          left: 0,
          right: 0,
          height: '6px',
          background: isDarkTheme 
            ? 'linear-gradient(90deg, #177ddc, #49aa19, #d89614, #d32029, #642ab5)' 
            : 'linear-gradient(90deg, #1677ff, #52c41a, #faad14, #ff4d4f, #722ed1)',
          borderRadius: '24px 24px 0 0',
          boxShadow: '0 2px 8px rgba(0,0,0,0.2)'
        }} />
        
        {/* 主标题区域 */}
        <div style={{
          textAlign: 'center',
          marginBottom: 40,
          position: 'relative'
        }}>
          <div style={{
            width: '60px',
            height: '60px',
            borderRadius: '50%',
            background: isDarkTheme 
              ? 'linear-gradient(135deg, #177ddc, #49aa19)' 
              : 'linear-gradient(135deg, #1677ff, #52c41a)',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center',
            margin: '0 auto 20px',
            boxShadow: '0 8px 24px rgba(0,0,0,0.2)',
            animation: 'pulse 2s ease-in-out infinite'
          }}>
            <UploadOutlined style={{
              fontSize: '24px',
              color: '#fff'
            }} />
          </div>
          
          <Typography.Title 
            level={2} 
            style={{ 
              color: isDarkTheme ? '#ffffff' : '#000000',
              transition: 'color 0.3s ease',
              margin: 0,
              fontWeight: 600
            }}
          >
            大文件切片上传
          </Typography.Title>
          
          <Typography.Text 
            style={{ 
              color: isDarkTheme ? '#ffffff' : '#666666',
              fontSize: '14px',
              display: 'block',
              marginTop: '8px'
            }}
          >
            支持断点续传 · 秒传 · 并发上传
          </Typography.Text>
        </div>
        
        {/* 文件上传区域 */}
        <Upload
          beforeUpload={file => { handleFileChange({ file }); return false; }}
          showUploadList={false}
          accept="*"
          disabled={uploading}
          style={{ width: '100%' }}
        >
          <div style={{
            border: `2px dashed ${isDarkTheme ? '#404040' : '#d9d9d9'}`,
            borderRadius: '16px',
            padding: '40px 20px',
            textAlign: 'center',
            background: isDarkTheme ? '#1a1a1a' : '#fafafa',
            transition: 'all 0.3s ease',
            cursor: 'pointer',
            position: 'relative',
            overflow: 'hidden'
          }}>
            <div style={{
              position: 'absolute',
              top: 0,
              left: 0,
              right: 0,
              bottom: 0,
              background: isDarkTheme 
                ? 'linear-gradient(45deg, transparent 30%, rgba(23, 125, 220, 0.1) 50%, transparent 70%)' 
                : 'linear-gradient(45deg, transparent 30%, rgba(22, 119, 255, 0.05) 50%, transparent 70%)',
              animation: 'shimmer 2s infinite'
            }} />
            
            <UploadOutlined style={{
              fontSize: '48px',
              color: isDarkTheme ? '#177ddc' : '#1677ff',
              marginBottom: '16px',
              display: 'block'
            }} />
            
            <Typography.Text 
              style={{ 
                color: isDarkTheme ? '#ffffff' : '#000000',
                fontSize: '18px',
                fontWeight: 500,
                display: 'block',
                marginBottom: '8px',
                position: 'relative',
                zIndex: 1
              }}
            >
              点击或拖拽文件到此处
            </Typography.Text>
            
            <Typography.Text 
              style={{ 
                color: isDarkTheme ? '#cccccc' : '#666666',
                fontSize: '14px',
                position: 'relative',
                zIndex: 1
              }}
            >
              支持任意格式，最大1GB
            </Typography.Text>
          </div>
        </Upload>
        
        {/* 文件信息和进度 */}
        {file && (
          <div style={{
            marginTop: '32px',
            animation: 'slideIn 0.5s ease-out'
          }}>
            {/* 文件信息卡片 */}
            <div style={{
              background: isDarkTheme 
                ? 'linear-gradient(145deg, #2a2a2a 0%, #1f1f1f 100%)' 
                : 'linear-gradient(145deg, #f8f9fa 0%, #ffffff 100%)',
              padding: '24px',
              borderRadius: '16px',
              border: isDarkTheme ? '1px solid #404040' : '1px solid #e8e8e8',
              transition: 'all 0.3s ease',
              boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
              marginBottom: '24px'
            }}>
              <div style={{
                display: 'flex',
                alignItems: 'center',
                marginBottom: '16px'
              }}>
                <div style={{
                  width: '40px',
                  height: '40px',
                  borderRadius: '8px',
                  background: isDarkTheme 
                    ? 'linear-gradient(135deg, #177ddc, #49aa19)' 
                    : 'linear-gradient(135deg, #1677ff, #52c41a)',
                  display: 'flex',
                  alignItems: 'center',
                  justifyContent: 'center',
                  marginRight: '12px'
                }}>
                  <UploadOutlined style={{ color: '#fff', fontSize: '16px' }} />
                </div>
                <div>
                  <Typography.Text 
                    strong 
                    style={{ 
                      color: isDarkTheme ? '#ffffff' : '#000000',
                      fontSize: '16px',
                      display: 'block'
                    }}
                  >
                    {file.name}
                  </Typography.Text>
                  <Typography.Text 
                    style={{ 
                      color: isDarkTheme ? '#ffffff' : '#666666',
                      fontSize: '14px'
                    }}
                  >
                    {(file.size / 1024 / 1024).toFixed(2)} MB
                  </Typography.Text>
                </div>
              </div>
              
              {/* 进度条 */}
              <div style={{ marginBottom: '16px' }}>
                <div style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  marginBottom: '8px'
                }}>
                  <Typography.Text 
                    style={{ 
                      color: isDarkTheme ? '#ffffff' : '#000000',
                      fontSize: '14px',
                      fontWeight: 500
                    }}
                  >
                    上传进度
                  </Typography.Text>
                  <Typography.Text 
                    style={{ 
                      color: isDarkTheme ? '#177ddc' : '#1677ff',
                      fontSize: '14px',
                      fontWeight: 600
                    }}
                  >
                    {progress}%
                  </Typography.Text>
                </div>
                
                <Progress 
                  percent={progress} 
                  status={progress === 100 ? "success" : uploading ? "active" : "normal"} 
                  showInfo={false}
                  strokeColor={isDarkTheme ? '#177ddc' : '#1677ff'}
                  trailColor={isDarkTheme ? '#404040' : '#f0f0f0'}
                  strokeWidth={8}
                  style={{ marginBottom: '0' }}
                />
              </div>
              
              {/* 上传统计 */}
              {uploading && (
                <div style={{
                  display: 'flex',
                  justifyContent: 'space-between',
                  alignItems: 'center',
                  padding: '16px',
                  background: isDarkTheme ? '#1f1f1f' : '#f5f5f5',
                  borderRadius: '12px',
                  border: isDarkTheme ? '1px solid #303030' : '1px solid #e8e8e8'
                }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>
                    <div style={{
                      width: '8px',
                      height: '8px',
                      borderRadius: '50%',
                      background: isDarkTheme ? '#177ddc' : '#1677ff',
                      animation: 'pulse 1.5s infinite'
                    }} />
                    <Typography.Text 
                      style={{ 
                        color: isDarkTheme ? '#ffffff' : '#000000',
                        fontSize: '14px'
                      }}
                    >
                      速度: {uploadSpeed}
                    </Typography.Text>
                  </div>
                  <Typography.Text 
                    style={{ 
                      color: isDarkTheme ? '#ffffff' : '#666666',
                      fontSize: '14px'
                    }}
                  >
                    剩余: {remainingTime}
                  </Typography.Text>
                </div>
              )}
            </div>
            
            {/* 控制按钮 */}
            <div style={{
              display: 'flex',
              gap: '12px',
              justifyContent: 'center'
            }}>
              <Button 
                type="primary" 
                onClick={startUpload} 
                disabled={uploading || progress === 100}
                size="large"
                style={{
                  background: isDarkTheme ? '#177ddc' : '#1677ff',
                  borderColor: isDarkTheme ? '#177ddc' : '#1677ff',
                  transition: 'all 0.3s ease',
                  height: '48px',
                  borderRadius: '12px',
                  fontWeight: 600,
                  fontSize: '16px',
                  minWidth: '120px',
                  boxShadow: '0 4px 12px rgba(0,0,0,0.15)'
                }}
              >
                {progress === 100 ? "✅ 已完成" : "🚀 开始上传"}
              </Button>
              
              <Button 
                icon={<PauseOutlined />} 
                onClick={handlePause} 
                disabled={!uploading || paused}
                size="large"
                style={{
                  color: isDarkTheme ? '#ffffff' : '#000000',
                  borderColor: isDarkTheme ? '#404040' : '#d9d9d9',
                  background: isDarkTheme ? '#2a2a2a' : '#fff',
                  transition: 'all 0.3s ease',
                  height: '48px',
                  borderRadius: '12px',
                  minWidth: '100px',
                  boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
                }}
              >
                暂停
              </Button>
              
              <Button 
                icon={<PlayCircleOutlined />} 
                onClick={handleResume} 
                disabled={uploading || !paused || progress === 100}
                size="large"
                style={{
                  color: isDarkTheme ? '#ffffff' : '#000000',
                  borderColor: isDarkTheme ? '#404040' : '#d9d9d9',
                  background: isDarkTheme ? '#2a2a2a' : '#fff',
                  transition: 'all 0.3s ease',
                  height: '48px',
                  borderRadius: '12px',
                  minWidth: '100px',
                  boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
                }}
              >
                恢复
              </Button>
            </div>
          </div>
        )}
        
        {/* 添加CSS动画 */}
        <style>{`
          @keyframes pulse {
            0%, 100% { opacity: 1; transform: scale(1); }
            50% { opacity: 0.8; transform: scale(1.05); }
          }
          
          @keyframes float {
            0%, 100% { transform: translateY(0px) rotate(0deg); }
            50% { transform: translateY(-20px) rotate(180deg); }
          }
          
          @keyframes shimmer {
            0% { transform: translateX(-100%); }
            100% { transform: translateX(100%); }
          }
          
          @keyframes slideIn {
            from { opacity: 0; transform: translateY(20px); }
            to { opacity: 1; transform: translateY(0); }
          }
        `}</style>
      </div>
    </div>
  );
};

export default Order;